﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Mvc;
using WalkingTec.Mvvm.Core.Extensions;
using ReceiptPrint.ViewModels.ExcelFileVMs;
using Newtonsoft.Json;
using System.Threading.Tasks;
using Magicodes.ExporterAndImporter.Excel;
using ReceiptPrint.Dto;
using NewLife.Log;
using NewLife.Serialization;
using System.Collections.Generic;
using NewLife;
using ReceiptPrint.Models;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using WalkingTec.Mvvm.Mvc.Binders;
using System.IO;
using System.Text;
using SQLitePCL;
using System.Drawing;
using Microsoft.AspNetCore.Components.RenderTree;
using System.Drawing.Imaging;

namespace ReceiptPrint.Controllers
{
    [AllRights]
    [ActionDescription("数据导入")]
    public partial class ExcelFileController : BaseController
    {
        #region Search
        [ActionDescription("Sys.Search")]
        public ActionResult Index()
        {
            var vm = Wtm.CreateVM<ExcelFileListVM>();
            return PartialView(vm);
        }

        [ActionDescription("Sys.Search")]
        [HttpPost]
        public string Search(ExcelFileSearcher searcher)
        {
            var vm = Wtm.CreateVM<ExcelFileListVM>(passInit: true);
            if (ModelState.IsValid)
            {
                vm.Searcher = searcher;
                return vm.GetJson(false);
            }
            else
            {
                return vm.GetError();
            }
        }

        #endregion

        #region Create
        [ActionDescription("Sys.Create")]
        public ActionResult Create()
        {
            var vm = Wtm.CreateVM<ExcelFileVM>();
            vm.Entity.Header = Global.Header;
            vm.Entity.SubHeader = Global.SubHeader;
            vm.Entity.Footer = Global.Footer;
            return PartialView(vm);
        }

        [HttpPost]
        [ActionDescription("Sys.Create")]
        [StringNeedLTGT]
        public async Task<ActionResult> Create(ExcelFileVM vm)
        {
            if (!ModelState.IsValid)
            {
                return PartialView(vm);
            }
            else
            {
                if (vm.Entity.FileId == Guid.Empty)
                {
                    vm.MSD.AddModelError("upload", "请选择数据文件");
                }
                if (!ModelState.IsValid)
                {
                    return PartialView(vm);
                }
                vm.Entity.Templates = new List<Template>();
                vm.Entity.ID = Global.GetId();
                var importer = new ExcelImporter();
                var file = DC.Set<FileAttachment>().Find(vm.Entity.FileId);
                List<CommodityDataDto> dtos = new List<CommodityDataDto>();
                var import = await importer.Import<CommodityDataDto>(Global.GetFullPath(Wtm, file.Path), labelingFilePath: "", (r) => {
                    if (r.Exception != null || r.HasError || r.RowErrors.Count > 0)
                    {
                        vm.MSD.AddModelError("excel", "数据格式错误");
                        if (r.Exception != null)
                        {
                            XTrace.WriteException(r.Exception);
                        }
                        if (r.RowErrors.Count > 0)
                        {
                            try
                            {
                                XTrace.WriteLine(r.RowErrors.ToJson());
                            }
                            catch { }
                        }
                    }
                    else
                    {
                        dtos.AddRange(r.Data);
                    }
                    return r;
                });
                if (!ModelState.IsValid)
                {
                    return PartialView(vm);
                }
                var types = DC.Set<CommodityType>().ToList();
                
                Dictionary<string, Template> dicTemplate = new Dictionary<string, Template>();
                var now = DateTime.Now;
                long max = Global.StartNumber;
                try 
                {
                    max = DC.Set<Template>().Max(x => x.Number);
                }
                catch { max = Global.StartNumber; }
                var number = max + Global.Step;
                for (var i = 0; i < dtos.Count; i++)
                {
                    var dto = dtos[i];
                    if (i > 0)
                    {
                        var pre = i - 1;
                        if (dto.DeliveryNumber.IsNullOrEmpty() || dto.DeliveryNumber.IsNullOrWhiteSpace())
                        {
                            dto.DeliveryNumber = dtos[pre].DeliveryNumber;
                        }
                        if (dto.CommodityType.IsNullOrEmpty() || dto.CommodityType.IsNullOrWhiteSpace())
                        {
                            dto.CommodityType = dtos[pre].CommodityType;
                        }
                        if (dto.CommodityName.IsNullOrEmpty() || dto.CommodityName.IsNullOrWhiteSpace())
                        {
                            dto.CommodityName = dtos[pre].CommodityName;
                        }

                        if (dto.CommodityNumber == null)
                        {
                            dto.CommodityNumber = dtos[pre].CommodityNumber;
                        }
                        if (dto.CommodityPrice == null)
                        {
                            dto.CommodityPrice = dtos[pre].CommodityPrice;
                        }
                        if (dto.OrderTime.IsNullOrEmpty() || dto.OrderTime.IsNullOrWhiteSpace())
                        {
                            dto.OrderTime = dtos[pre].OrderTime;
                        }
                    }
                    Template template = null;
                    var deliveryNumber = $"{dto.DeliveryNumber}.x";
                    if (!dicTemplate.ContainsKey(deliveryNumber))
                    {
                        var orderTime = dto.OrderTime.ToDateTime();
                        template = new Template()
                        {
                            ID = Global.GetId(),
                            Name = deliveryNumber,
                            CreateTime = now,
                            CreateBy = Wtm.LoginUserInfo.ITCode,
                            ExcelFileId = vm.Entity.ID,
                            Header = vm.Entity.Header,
                            SubHeader = string.Format(vm.Entity.SubHeader, number, orderTime.ToString("MM/dd/yyyy"), orderTime.ToString("HH:mm")),
                            Footer = vm.Entity.Footer,
                            Number = number,
                            ReceiptInfoes = new List<ReceiptInfo>()
                        };
                        dicTemplate.Add(deliveryNumber, template);
                        vm.Entity.Templates.Add(template);
                    }
                    else
                    {
                        template = dicTemplate[deliveryNumber];
                    }
                    Tax tax = Tax.Zero;
                    var type = types.FirstOrDefault(x => x.Name == dto.CommodityType);
                    if (type != null)
                    {
                        tax = type.Tax;
                    }
                    var receiptInfo = new ReceiptInfo()
                    {
                        TemplateId = template.ID,
                        Name = dto.CommodityName,
                        Price = (float)(dto.CommodityPrice ?? 0m),
                        Number = (float)(dto.CommodityNumber ?? 1m),
                        Tax = tax
                    };
                    template.ReceiptInfoes.Add(receiptInfo);
                    number = max + Global.Step;
                }
                foreach (var v in dicTemplate)
                {
                    var sum = v.Value.ReceiptInfoes.Sum(x => x.Price * x.Number);
                    v.Value.Money = (((int)(sum / 100)) + 1) * 100; 
                }
                vm.DoAdd();
                if (!ModelState.IsValid)
                {
                    vm.DoReInit();
                    return PartialView(vm);
                }
                else
                {
                    return FFResult().CloseDialog().RefreshGrid();
                }
            }
        }
        #endregion

        #region Edit
        [ActionDescription("Sys.Edit")]
        public ActionResult Edit(string id)
        {
            var vm = Wtm.CreateVM<ExcelFileVM>(id);
            return PartialView(vm);
        }

        [ActionDescription("Sys.Edit")]
        [HttpPost]
        [ValidateFormItemOnly]
        public ActionResult Edit(ExcelFileVM vm)
        {
            if (!ModelState.IsValid)
            {
                return PartialView(vm);
            }
            else
            {
               
                vm.DoEdit();
                if (!ModelState.IsValid)
                {
                    vm.DoReInit();
                    return PartialView(vm);
                }
                else
                {
                    return FFResult().CloseDialog().RefreshGridRow(vm.Entity.ID);
                }
            }
        }
        #endregion

        #region Delete
        [ActionDescription("Sys.Delete")]
        public ActionResult Delete(string id)
        {
            var vm = Wtm.CreateVM<ExcelFileVM>(id);
            return PartialView(vm);
        }

        [ActionDescription("Sys.Delete")]
        [HttpPost]
        public ActionResult Delete(string id, IFormCollection nouse)
        {
            var vm = Wtm.CreateVM<ExcelFileVM>(id);
            vm.DoDelete();
            if (!ModelState.IsValid)
            {
                return PartialView(vm);
            }
            else
            {
                return FFResult().CloseDialog().RefreshGrid();
            }
        }
        #endregion

        #region Details
        [ActionDescription("Sys.Details")]
        public ActionResult Details(string id)
        {
            var vm = Wtm.CreateVM<ExcelFileVM>(id);
            return PartialView(vm);
        }
        #endregion

        #region BatchEdit
        [HttpPost]
        [ActionDescription("Sys.BatchEdit")]
        public ActionResult BatchEdit(string[] IDs)
        {
            var vm = Wtm.CreateVM<ExcelFileBatchVM>(Ids: IDs);
            return PartialView(vm);
        }

        [HttpPost]
        [ActionDescription("Sys.BatchEdit")]
        public ActionResult DoBatchEdit(ExcelFileBatchVM vm, IFormCollection nouse)
        {
            if (!ModelState.IsValid || !vm.DoBatchEdit())
            {
                return PartialView("BatchEdit",vm);
            }
            else
            {
                return FFResult().CloseDialog().RefreshGrid().Alert(Localizer["Sys.BatchEditSuccess", vm.Ids.Length]);
            }
        }
        #endregion

        #region BatchDelete
        [HttpPost]
        [ActionDescription("Sys.BatchDelete")]
        public ActionResult BatchDelete(string[] IDs)
        {
            var vm = Wtm.CreateVM<ExcelFileBatchVM>(Ids: IDs);
            return PartialView(vm);
        }

        [HttpPost]
        [ActionDescription("Sys.BatchDelete")]
        public ActionResult DoBatchDelete(ExcelFileBatchVM vm, IFormCollection nouse)
        {
            if (!ModelState.IsValid || !vm.DoBatchDelete())
            {
                return PartialView("BatchDelete",vm);
            }
            else
            {
                return FFResult().CloseDialog().RefreshGrid().Alert(Localizer["Sys.BatchDeleteSuccess", vm.Ids.Length]);
            }
        }
        #endregion

        #region Import
		[ActionDescription("Sys.Import")]
        public ActionResult Import()
        {
            var vm = Wtm.CreateVM<ExcelFileImportVM>();
            return PartialView(vm);
        }

        [HttpPost]
        [ActionDescription("Sys.Import")]
        public ActionResult Import(ExcelFileImportVM vm, IFormCollection nouse)
        {
            if (vm.ErrorListVM.EntityList.Count > 0 || !vm.BatchSaveData())
            {
                return PartialView(vm);
            }
            else
            {
                return FFResult().CloseDialog().RefreshGrid().Alert(Localizer["Sys.ImportSuccess", vm.EntityList.Count.ToString()]);
            }
        }
        #endregion

        [ActionDescription("Sys.Export")]
        [HttpPost]
        public IActionResult ExportExcel(ExcelFileListVM vm)
        {
            return vm.GetExportData();
        }
        [ActionDescription("导出")]
        public ActionResult ExportFile(long id)
        {
            var entity = DC.Set<ExcelFile>().Include(x => x.Templates).ThenInclude(y => y.ReceiptInfoes).First(x => x.ID == id);
            var exportPath = Path.Combine(Global.GetFullPath(Wtm,Wtm.ConfigInfo.AppSettings["ExportPath"]),entity.Name.Replace(".xlsx","").ToString());
            if (exportPath != null && !System.IO.Directory.Exists(exportPath))
            {
                System.IO.Directory.CreateDirectory(exportPath);
            }
            foreach (var template in entity.Templates)
            {
                string outName = $"{template.Name}.{(Global.UsePdf ? "pdf":"jpg")}";

                StringBuilder stringBuilder = new StringBuilder();
                
                stringBuilder.AppendLine(template.Header);
                stringBuilder.AppendLine(ReportHelper.GetLine());
                stringBuilder.AppendLine(template.SubHeader);
                stringBuilder.AppendLine(ReportHelper.GetLine());
                stringBuilder.AppendLine(ReportHelper.GetERU());
                stringBuilder.AppendLine(ReportHelper.GetReceiptInfo(template.ReceiptInfoes));

                stringBuilder.AppendLine(ReportHelper.GetBelastingtariefAndMoney(template.Money, template.ReceiptInfoes));

                stringBuilder.AppendLine(template.Footer);

                var text = stringBuilder.ToString();
                var rows = text.Split("\n");
                int x = 5;
                int y = 10;
                int w = 142;
                int h = 10 * rows.Length + 30;
                float fontSize = entity.FontSize;
                int step = 10;
                if (Global.UsePdf)
                {
                    PdfSharpCore.Pdf.PdfDocument document = new PdfSharpCore.Pdf.PdfDocument();
                    PdfSharpCore.Pdf.PdfPage pageNewRenderer = document.AddPage();
                    pageNewRenderer.Width = w;
                    pageNewRenderer.Height = h;
                    PdfSharpCore.Drawing.XGraphics renderer = PdfSharpCore.Drawing.XGraphics.FromPdfPage(pageNewRenderer);

                    foreach (var row in rows)
                    {
                        renderer.DrawString(
                          row.Trim('\r')
                        , new PdfSharpCore.Drawing.XFont(ReportHelper.FontName, fontSize)
                        , PdfSharpCore.Drawing.XBrushes.Black
                        , new PdfSharpCore.Drawing.XPoint(x, y)
                         );
                        y += step;
                    }


                    SaveDocument(document, exportPath, outName);
                }
                else
                {
                    w = 390;
                    x = 10;
                    h = 22 * rows.Length + 30;
                    step = 22;
                    string filePath = Path.Combine(exportPath,outName);
                    Font font = new Font(ReportHelper.FontName, fontSize);
                    //绘笔颜色
                    SolidBrush brush = new SolidBrush(Color.Black);
                    using Bitmap image = new Bitmap(w, h);
                    using Graphics g = Graphics.FromImage(image);
                    g.Clear(Color.White);
                    foreach (var row in rows)
                    {
                        g.DrawString(
                          row.Trim('\r')
                        , font
                        , brush
                        , new Point(x, y)
                         );
                        y += step;
                    }
                    
                    //保存图片
                    image.Save(filePath, ImageFormat.Jpeg);
                }
            }
            System.Diagnostics.Process.Start("Explorer.exe", exportPath);
            return FFResult().Message("导出完成");
        }

        private static void SaveDocument(PdfSharpCore.Pdf.PdfDocument document, string outFilePath, string name)
        {
            //if (outFilePath != null && !System.IO.Directory.Exists(outFilePath))
            //{
            //    System.IO.Directory.CreateDirectory(outFilePath);
            //}
           
            document.Save(Path.Combine(outFilePath,name));
        }
    }
}
